package com.glodon.zhuanli.system.controller;

import com.glodon.framework.common.Constants;
import com.glodon.framework.common.util.DTOUtil;
import com.glodon.framework.common.util.support.DTOCallbackHandler;
import com.glodon.framework.web.util.ResponseParam;
import com.glodon.zhuanli.ZLConstants;
import com.glodon.zhuanli.common.ZhuanliBaseController;
import com.glodon.zhuanli.common.sms.SMSPasswordModify;
import com.glodon.zhuanli.system.entity.SysUser;
import com.glodon.zhuanli.system.service.SysUserService;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Controller
@RequestMapping(value=SysUserController.BASE_PATH)
public class SysUserController extends ZhuanliBaseController {

    public static final String PWD_VCODE = "pwd_vcode" ;

    /**
     * 当前模块跟路径
     */
    public static final String BASE_PATH = "/system/sysuser" ;

    @Autowired
    private SysUserService sysUserService ;

    public SysUserController(){
        this.addDictionaryProperty( "status" , "user_status" ) ;
        this.addDictionaryProperty( "type" , "user_identity" ) ;
    }

    @GetMapping
    public ModelAndView index(){
        ModelAndView mv = new ModelAndView() ;
        //设置返回的主视图名称
        mv.setViewName(BASE_PATH+"/sysuser_index") ;
        //请求来源，默认查询系统管理员创建的用户
        mv.addObject("source" , ZLConstants.RECORD_SOURCE.SYSTEM ) ;

        return mv ;
    }

    @RequestMapping(value = "/company" , method=RequestMethod.GET)
    public ModelAndView companyIndex(){
        ModelAndView mv = new ModelAndView() ;
        //如果是企业的用户管理，则返回到企业的视图中
        mv.setViewName(BASE_PATH+"/sysuser_company_index") ;
        //请求来源，默认查询系统管理员创建的用户
        mv.addObject("source" ,  ZLConstants.RECORD_SOURCE.COMPANY) ;

        return mv ;
    }

    /**
     * 返回修改密码的页面
     * @return
     * @throws Exception
     */
    @GetMapping(value="pwd")
    public ModelAndView detail() throws Exception{
        ModelAndView editView = new ModelAndView(BASE_PATH+"/sysuser_pwd") ;

        return editView ;
    }

    /**
     * 获取短信验证码
     * @param mobile
     * @return
     * @throws Exception
     */
    @PostMapping(value="pwdvcode")
    @ResponseBody
    public ResponseParam getPwdVCode(@RequestParam String mobile ) throws Exception{
        if( StringUtils.isBlank(mobile) || !isMobile( mobile ) ){
            return ResponseParam.fail().addMessage("手机号不正确") ;
        }

        String userid = getLoginUserId() ;
        if( StringUtils.isBlank(userid) ){
            return ResponseParam.fail().addMessage("请先登录当前系统") ;
        }
        SysUser sysUser =sysUserService.get( userid ) ;
        if( sysUser==null || !StringUtils.equalsIgnoreCase( mobile , sysUser.getMobile() ) ){
            return ResponseParam.fail().addMessage("请使用当前登录用户的手机号获取验证码") ;
        }

        //发送验证码
        SMSPasswordModify smsPasswordModify = zlsmsService.sendMessage( new SMSPasswordModify(mobile) ) ;
        if( !smsPasswordModify.isSuccess() ){
            return ResponseParam.fail().addMessage(smsPasswordModify.getMessage()) ;
        }

        //设置验证码
        getHttpServletRequest().getSession().setAttribute( PWD_VCODE , smsPasswordModify.getVcode() ) ;

        return ResponseParam.success() ;
    }

    /**
     * 提交密码请求
     * @param vcode
     * @param pwd
     * @return
     * @throws Exception
     */
    @PostMapping(value="pwd")
    @ResponseBody
    public ResponseParam updatePwd(@RequestParam String vcode  , @RequestParam String pwd) throws Exception{
        String userId = getLoginUserId() ;
        if( StringUtils.isBlank(userId) ){
            return ResponseParam.fail().addMessage("当前用户未登录") ;
        }

        //获取存储在session中的短信验证码
        Object sessionVCode = getHttpServletRequest().getSession().getAttribute( PWD_VCODE ) ;
        if( sessionVCode==null || !StringUtils.equalsIgnoreCase( sessionVCode.toString()  ,vcode ) ){
            return ResponseParam.fail().addMessage("短信验证码不正确") ;
        }

        //执行重置密码
        sysUserService.resetPassword( userId , pwd ) ;

        return ResponseParam.success() ;
    }

    /**
     * 记录分页查询
     * @param pageNum 分页号，由0开始
     * @param pageSize 每页记录数，默认为10
     * @return
     * @throws Exception
     */
    @RequestMapping(value="query" , method=RequestMethod.POST)
    @ResponseBody
    public ResponseParam query(
            @RequestParam(required=false , value="pagenum" ,
                    defaultValue=""+Constants.DEFAULT_START_PAGE)int pageNum ,
            @RequestParam(required=false , value="pagesize" ,
                    defaultValue=""+Constants.DEFAULT_PAGESIZE)int pageSize) throws Exception {
        ResponseParam responseParam = ResponseParam.success() ;
        //获取查询参数
        Map<String, Object> searchParam = getParametersStartingWith(getServletRequest(),
                Constants.DEFAULT_SEARCH_PREFIX) ;

        //如果当前用户属于某一个企业，则只能查看到所属企业下的用户
        String userCompanyId = getUserCompanyId() ;
        if( StringUtils.isNotBlank(userCompanyId) ){
            searchParam.put("companyId" , userCompanyId) ;
        }

        //执行分页查询
        Page<SysUser> sysUserPage = sysUserService.queryByPage(searchParam , pageNum , pageSize) ;

        //数据库实体与前端展示字段之间的转换，需要指定前端展示需要的字段
        List<Map<String, Object>> sysUserList = DTOUtil.toDTOExcludeFields(sysUserPage.getContent(),
                null , getDtoCallbackHandler()) ;

        return buildEasyUIPageResult( sysUserPage , sysUserList ) ;
    }

    /**
     * 查询用户列表
     * @return
     * @throws Exception
     */
    @RequestMapping(value="list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String type , @RequestParam(required = false) String includeid) throws Exception {
        Map<String,Object> searchParams = Maps.newHashMap() ;

        //执行分页查询
        List<SysUser> sysUsers = sysUserService.queryAll( searchParams ) ;

        //已经关联的用户id
        Set<String> linkedUserIds = null ;

        //构建查询结果列表
        List<Map<String,String>> resultList = Lists.newArrayList() ;
        if( sysUsers != null ){
            for ( SysUser sysUser : sysUsers ) {
                if( linkedUserIds!=null && linkedUserIds.contains( sysUser.getId() ) ){
                    continue;
                }
                Map<String,String> item = Maps.newHashMapWithExpectedSize( 2 ) ;
                item.put("id" , sysUser.getId()) ;
                item.put("text" , sysUser.getName() ) ;

                resultList.add( item ) ;
            }
        }

        return resultList ;
    }

	/**
	 * 返回编辑页面的内容
	**/
	@RequestMapping(value={"edit" , "new" , "detail"})
    public ModelAndView detail(@RequestParam(required = false) String id) throws Exception{
        ModelAndView editView = new ModelAndView(BASE_PATH+"/sysuser_edit") ;

        //对象类型
        Object resultItem = new SysUser() ;

        if( StringUtils.isNotBlank(id) ){
            resultItem = sysUserService.get(id) ;
        }
        //覆盖实体对象

        resultItem = DTOUtil.toDTOExcludeFields( resultItem , null , getDtoCallbackHandler() ) ;

        //判断是否为只读模式，只有url中包含/detail才是只读模式
        editView.addObject( "detail" , getHttpServletRequest().getRequestURI().indexOf("/detail")!=-1 ) ;

        editView.addObject( "data" , resultItem ) ;

        //如果当前用户属于某一个企业，标识来源是否为系统
        String userCompanyId = getUserCompanyId() ;
        if( StringUtils.isNotBlank(userCompanyId) ){
            editView.addObject("iscompany" ,true ) ;
        }else{
            editView.addObject("iscompany" ,false ) ;
        }

        return editView ;
    }

    @PostMapping(value={"reset"})
    @ResponseBody
    public ResponseParam reset(@RequestParam(required = true) String ids) throws Exception{

        if( StringUtils.isBlank(ids) ){
            return ResponseParam.fail() ;
        }
        List<String> idList = Splitter.on(",").omitEmptyStrings().trimResults().splitToList( ids ) ;
        for (String id : idList) {
            sysUserService.resetPassword( id , SysUserService.DEFAULT_PASSWORD ) ;
        }

        return ResponseParam.success().addMessage("密码重置成功，密码为："+SysUserService.DEFAULT_PASSWORD) ;
    }
   
    /**
     * 保存实体对象 。在保存之前进行后端实体属性的验证，保证添加的数据符合业务要求。<br>
     * 如果实体id不为空，进行更新操作，否则进行添加。
     * @param sysUser
     * @return
     * @throws Exception
     */
    @RequestMapping(value="save" , method = RequestMethod.POST)
    @ResponseBody
    public ResponseParam save(@Valid SysUser sysUser) throws Exception{

        boolean existUserCode = sysUserService.existUserCode( sysUser.getCode() , sysUser.getId() ) ;
        if( existUserCode ){
            return ResponseParam.updateFail().addMessage("用户编码已经被使用") ;
        }

        boolean existUserMobile = sysUserService.existMobile( sysUser.getMobile() , sysUser.getId() ) ;
        if( existUserMobile ){
            return ResponseParam.updateFail().addMessage("用户手机号已经被使用") ;
        }

        String userCompanyId = getUserCompanyId() ;
        if( StringUtils.isNotBlank(userCompanyId) ){
            sysUser.setCompanyId( userCompanyId ) ;
            sysUser.setSource( ZLConstants.RECORD_SOURCE.COMPANY );
        }

        //id不为空，进行更新操作，否则进行添加
        if(StringUtils.isNotBlank(sysUser.getId())){
			//由请求参数中获取需要更新的字段
			Set<String> updateFields = Sets.newHashSet( getHttpServletRequest().getParameterMap().keySet() ) ;
            updateFields.add("companyId") ;
            updateFields.add("source") ;

			//按照字段更新对象
			sysUserService.update(sysUser , updateFields) ;

			return ResponseParam.updateSuccess() ;
        }else{
			sysUserService.saveUser(sysUser , null);
			return ResponseParam.saveSuccess().addMessage("新建用户成功，密码为："+SysUserService.DEFAULT_PASSWORD) ;
        }
    }

    /**
     * 删除信息
     * @param ids
     * @return
     */
    @RequestMapping(value="delete" , method=RequestMethod.POST)
    @ResponseBody
    public ResponseParam delete(@RequestParam(required=true , value="ids") String ids){
        if(StringUtils.isBlank(ids)){
            return ResponseParam.deleteFail() ;
        }
        //执行删除
        sysUserService.delete(ids.split(",")) ;

        return ResponseParam.deleteSuccess() ;
    }

    /**
     * 获取PO到DTO转换的接口。主要用于在前端展示数据之前首先将数据格式处理完成。
     * @return
     */
    public DTOCallbackHandler getDtoCallbackHandler() {
        DTOCallbackHandler dtoCallbackHandler = new DTOCallbackHandler() {
            @Override
            public void doHandler(Map<String, Object> dtoMap) {
            }
        };

        return getDTOCallbackHandlerProxy(dtoCallbackHandler,true);
    }

}